package org.jeecg.modules.importExcelAnalysis.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.common.utils.DateUtil;
import org.jeecg.modules.common.utils.PoiExcelUtils;
import org.jeecg.modules.importExcelAnalysis.entity.ImportExcelAnalysis;
import org.jeecg.modules.importExcelAnalysis.vo.ImportExcelAnalysisVo;
import org.jeecg.modules.importExcelAnalysis.service.IImportExcelAnalysisService;
import org.jeecgframework.poi.excel.annotation.ExcelTarget;
import org.springframework.beans.BeanUtils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.modules.common.api.ISysInfo;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.common.baseentity.BaseApiEntity;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.modules.student.service.IStuStudentService;
import org.jeecg.modules.classes.service.ICouClassService;
import org.jeecg.modules.classes.entity.CouClass;
import org.jeecg.modules.student.entity.StuStudent;

/**
 * @Description: import_excel_analysis
 * @author: baochangrong
 * @Date: 2022-06-21
 * @Version: V1.0
 */
@Api(tags = "import_excel_analysis")
@RestController
@RequestMapping("/importExcelAnalysis/importExcelAnalysis")
@Slf4j
public class ImportExcelAnalysisController extends JeecgController<ImportExcelAnalysis, IImportExcelAnalysisService> {
    @Autowired
    private ISysBaseAPI sysBaseAPI;
    @Autowired
    private ISysInfo sysInfo;
    @Autowired
    private IImportExcelAnalysisService importExcelAnalysisService;
    @Autowired
    private IStuStudentService stuStudentService;
    @Autowired
    private ICouClassService couClassService;

    /**
     * 分页列表查询
     *
     * @param importExcelAnalysis
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "import_excel_analysis-分页列表查询")
    @ApiOperation(value = "import_excel_analysis-分页列表查询", notes = "import_excel_analysis-分页列表查询")
    @GetMapping(value = "/list")
    public Result<?> queryPageList(ImportExcelAnalysis importExcelAnalysis,
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) {
        //获取当前登录用户信息 把租户 部门 身份 学期 学年等基本信息信息赋值克隆给importExcelAnalysis
        BaseApiEntity baseApiEntity = sysInfo.querySysInfoCloneObj(req, importExcelAnalysis,false); //获取当前登录用户信息 把租户 部门 身份 学期 学年等基本信息信息赋值给vo
        //需要用到的时候打开注释，用于用户身份识别
        //this.reSetObjectValue(baseApiEntity,importExcelAnalysis);

        importExcelAnalysis.setCreateTime(null);
        importExcelAnalysis.setUpdateTime(null);
        importExcelAnalysis.setSysOrgCode(null);
        importExcelAnalysis.setCreateBy(null);
        importExcelAnalysis.setUpdateBy(null);
        QueryWrapper<ImportExcelAnalysis> queryWrapper = QueryGenerator.initQueryWrapper(importExcelAnalysis, req.getParameterMap());
        List orders = new ArrayList();
        orders.add("class_name");
        orders.add("student_name");
        orders.add("topic_num");
        queryWrapper.orderBy(true, true, orders);
        Page<ImportExcelAnalysis> page = new Page<ImportExcelAnalysis>(pageNo, pageSize);
        IPage<ImportExcelAnalysis> pageList = importExcelAnalysisService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    /**
     * 解析数据
     * 科目分项成绩、科目成绩
     *
     * @param importExcelAnalysis
     * @return
     */
    @AutoLog(value = "import_excel_analysis-解析数据")
    @ApiOperation(value = "import_excel_analysis-添加", notes = "import_excel_analysis-解析数据")
    @PostMapping(value = "/analysisExaminationData")
    public Result<?> analysisExaminationData(@RequestBody ImportExcelAnalysisVo importExcelAnalysis, HttpServletRequest req) {
        BaseApiEntity baseApiEntity = sysInfo.querySysInfoCloneObj(req, importExcelAnalysis,false);
        importExcelAnalysis.setUpdateTime(null);
        importExcelAnalysis.setUpdateBy(null);
        String batchNumber = baseApiEntity.getUsername() + DateUtil.getNow("yyyyMMddHHmm");
        importExcelAnalysis.setBatchNumber(batchNumber);

        Assert.hasText(importExcelAnalysis.getExaminationId(), "考试没有选择，请选择后重新解析");
        Assert.hasText(importExcelAnalysis.getGradeId(), "年级没有选择，请选择后重新解析");
        return Result.OK(importExcelAnalysisService.analysisSubjectExaminationData(importExcelAnalysis));
    }

    /**
     * 解析数据
     * 科目总成绩
     * @param importExcelAnalysis
     * @return
     */
    @AutoLog(value = "import_excel_analysis-解析科目总成绩")
    @ApiOperation(value = "import_excel_analysis-添加", notes = "import_excel_analysis-解析科目总成绩")
    @PostMapping(value = "/analysisAchievementExamData")
    public Result<?> analysisAchievementExamData(@RequestBody ImportExcelAnalysisVo importExcelAnalysis, HttpServletRequest req) {
        BaseApiEntity baseApiEntity = sysInfo.querySysInfoCloneObj(req, importExcelAnalysis,false);
        importExcelAnalysis.setUpdateTime(null);
        importExcelAnalysis.setUpdateBy(null);
        String batchNumber = baseApiEntity.getUsername() + DateUtil.getNow("yyyyMMddHHmm");
        importExcelAnalysis.setBatchNumber(batchNumber);

        Assert.hasText(importExcelAnalysis.getExaminationId(), "考试没有选择，请选择后重新解析");
        Assert.hasText(importExcelAnalysis.getGradeId(), "年级没有选择，请选择后重新解析");
        return Result.OK(importExcelAnalysisService.analysisAchievementExamData(importExcelAnalysis));
    }


    /**
     * 添加
     *
     * @param importExcelAnalysis
     * @return
     */
    @AutoLog(value = "import_excel_analysis-添加")
    @ApiOperation(value = "import_excel_analysis-添加", notes = "import_excel_analysis-添加")
    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody ImportExcelAnalysis importExcelAnalysis, HttpServletRequest req) {
        sysInfo.querySysInfoCloneObj(req, importExcelAnalysis);
        importExcelAnalysis.setUpdateTime(null);
        importExcelAnalysis.setUpdateBy(null);
        importExcelAnalysisService.save(importExcelAnalysis);
        return Result.OK("添加成功！");
    }

    /**
     * 编辑
     *
     * @param importExcelAnalysis
     * @return
     */
    @AutoLog(value = "import_excel_analysis-编辑")
    @ApiOperation(value = "import_excel_analysis-编辑", notes = "import_excel_analysis-编辑")
    @PutMapping(value = "/edit")
    public Result<?> edit(@RequestBody ImportExcelAnalysis importExcelAnalysis, HttpServletRequest req) {
        sysInfo.querySysInfoCloneObj(req, importExcelAnalysis);
        importExcelAnalysis.setCreateBy(null);
        importExcelAnalysis.setCreateTime(null);
        importExcelAnalysisService.updateById(importExcelAnalysis);
        return Result.OK("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "import_excel_analysis-通过id删除")
    @ApiOperation(value = "import_excel_analysis-通过id删除", notes = "import_excel_analysis-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        importExcelAnalysisService.removeById(id);
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "import_excel_analysis-批量删除")
    @ApiOperation(value = "import_excel_analysis-批量删除", notes = "import_excel_analysis-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.importExcelAnalysisService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "import_excel_analysis-通过id查询")
    @ApiOperation(value = "import_excel_analysis-通过id查询", notes = "import_excel_analysis-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
        ImportExcelAnalysis importExcelAnalysis = importExcelAnalysisService.getById(id);
        if (importExcelAnalysis == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(importExcelAnalysis);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param importExcelAnalysis
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, ImportExcelAnalysis importExcelAnalysis) {
        return super.exportXls(request, importExcelAnalysis, ImportExcelAnalysis.class, "import_excel_analysis");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {

        String examinationId = request.getHeader("examination-id");
        String gradeId = request.getHeader("grade-id");
        String classId = request.getHeader("class-id");
        String examinationPaperId = request.getHeader("examination-paper-id");
        Assert.hasText(examinationId, "考试没有选择");
        Assert.hasText(gradeId, "年级没有选择");
        Assert.hasText(classId, "班级没有选择");
        Assert.hasText(examinationPaperId, "试卷没有选择");
        ImportExcelAnalysisVo importExcelAnalysisVo = new ImportExcelAnalysisVo();
        importExcelAnalysisVo.setClassId(classId);
        importExcelAnalysisVo.setGradeId(gradeId);
        importExcelAnalysisVo.setExaminationId(examinationId);
        importExcelAnalysisVo.setExaminationPaperId(examinationPaperId);

        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            MultipartFile file = entity.getValue();// 获取上传文件对象
            try {
                long start = System.currentTimeMillis();
                List<ImportExcelAnalysis> importExeclAnalysisList = importExcelAnalysisService.importTarget(file, importExcelAnalysisVo);
                importExcelAnalysisService.saveBatch(importExeclAnalysisList);
                log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");
                if (importExeclAnalysisList.size() <= 0) {
                    return Result.error("文件导入失败: 请检查文件格式，是否符合标准格式，是否按页面提示文件类型导入！");
                }
                return Result.OK("文件导入成功，导入数据：" + importExeclAnalysisList.size() + "条");
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return Result.error("文件导入失败:" + e.getMessage());
            } finally {
                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return Result.error("文件导入失败！");
    }

    /**
     * 有需要身份识别的业务需打开下方注释补充查询条件就可以了
     * 根据业务需要设置查询参数，不同身份的用户不同的查询参数、得到不同的查询结果
     * 注意：有些业务并不需要身份识别，有些业务必须识别身份:4学生用户只能查自己的数据不能查别人的，6班级用户只能查自己班级的数据不能查其他班级的数据，
     * 3老师只能查老师所在部门和下级部门的数据，1普通用户（一般是非教学用户）
     *
     * @param baseApiEntity
     * @return Object
     */
    private ImportExcelAnalysis reSetObjectValue(BaseApiEntity baseApiEntity, ImportExcelAnalysis importExcelAnalysis) {
        //1.获取用户身份 userIdentity loginUser.getUserIdentity() 用户身份字典码user_identity， 3教师 4学生 5家长 6班级  1普通用户 2上级部门负责人
        //2.获取用户id loginUser.getId()
        int userIdentity = baseApiEntity.getUserIdentity();//获取当前登录用户身份：字典码 user_identity，3教师 4学生 5家长 6班级  1普通用户 2上级部门负责人
        String userId = baseApiEntity.getLoginUser().getId(); //当前登录用户id

        //有需要身份识别的业务需打开下方注释补充查询条件就可以了
        //根据业务需要设置查询参数，不同身份的用户不同的查询参数、得到不同的查询结果
        //注意：有些业务并不需要身份识别，有些业务必须识别身份:4学生用户只能查自己的数据不能查别人的，6班级用户只能查自己班级的数据不能查其他班级的数据，3老师只能查老师所在部门和下级部门的数据，1普通用户（一般是非教学用户） 2上级部门负责人只能查所在部门和下级部门的数据

        //  //userIdentity 用户身份字典码user_identity， 3教师 4学生 5家长 6班级  1普通用户 2上级部门负责人
        // // 学生、老师、班级、家长，都有绑定用户的user_id字段，可以根据user_id查询到对应的学生、老师、班级 基础档案信息
        if (userIdentity == 4) {
            //学生身份只能查看自己的数据，不能查看别人的
            StuStudent student = stuStudentService.getStuStudentByUserId(userId);
            importExcelAnalysis.setSysOrgCode(null); //当前用户和业务数据可能不在同一个部门，需设置为null，例如：学生张三属于七年级部门，成绩数据在初中教学部
        } else if (userIdentity == 5) {
            //家长身份只能查看孩子的数据，注意一个家长可能有多个孩子 一个孩子属于多个家长
            importExcelAnalysis.setSysOrgCode(null); //当前用户和业务数据可能不在同一个部门，需设置为null，例如：家长属于家长部，学生张三属于七年级部门，成绩数据在初中教学部
        } else if (userIdentity == 6) {
            //班级身份只能查看自己班级的数据
            CouClass couClass = couClassService.getCouClassByUserID(userId);
            importExcelAnalysis.setSysOrgCode(null);
            importExcelAnalysis.setSysOrgCode(null); //当前用户和业务数据可能不在同一个部门，需设置为null，例如：某班级属于七年级部门，成绩数据在初中教学部
        } else if (userIdentity == 3) {
            //老师身份，可以查看当前部门和下级子集部门的数据
            //(如果考虑老师只能查看所教授科目、所教授班级学生的数据，则与普通用户有区分，否则是一样的)
            importExcelAnalysis.setSysOrgCode(baseApiEntity.getSubDepSysOrgCodes());
        } else if (userIdentity == 3 || userIdentity == 1 || userIdentity == 2) {
            //普通用户身份、部门负责人（领导），可以查看当前部门和下级子集部门的数据
            importExcelAnalysis.setSysOrgCode(baseApiEntity.getSubDepSysOrgCodes());
        } else {
            //其他身份或默认设置
            importExcelAnalysis.setSysOrgCode(baseApiEntity.getSubDepSysOrgCodes());
        }

        return importExcelAnalysis;
    }

}
